package grapid.util;

import grapid.Grapid;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * JSON
 * 
 * @author grapid
 * @version 2.0
 * 
 */
public class GJSON {

	/**
	 * 页面输出编码
	 */
	private String characterEncoding = Grapid.DEFAULT_GJSON_CHARACTERENCODING;
	/**
	 * jQuery跨域请求回调函数名
	 */
	private String jsoncallbackMethodName = Grapid.DEFAULT_GJSON_JSONCALLBACKMETHODNAME;

	/**
	 * 数据
	 */
	private TreeMap<String, Object> data = new TreeMap<String, Object>();

	/**
	 * 添加数据
	 * 
	 * @param key
	 *            名
	 * @param value
	 *            值
	 */
	public void addData(String key, Object value) {
		data.put(key, value);
	}

	/**
	 * 根据key删除数据
	 * 
	 * @param key
	 *            名
	 */
	public void removeData(String key) {
		data.remove(key);
	}

	/**
	 * 将数据转换为字符串形式
	 * 
	 * @return 返回String类型JSON数据
	 */
	@SuppressWarnings("unchecked")
	public String encode() {
		String result = "";
		for (String key : data.keySet()) {
			Object value = data.get(key);
			if (value instanceof String)
				result += ", \""
						+ key
						+ "\" : \""
						+ value.toString().replaceAll("\"", "\\\\\"").replaceAll("\r", "&#13;").replaceAll("\n",
								"&#10;") + "\"";
			else if (value instanceof Integer || value instanceof Long || value instanceof Float
					|| value instanceof Double)
				result += ", \"" + key + "\" : " + value;
			else if (value instanceof Boolean)
				result += ", \"" + key + "\" : " + value;
			else if (value instanceof GJSON)
				result += ", \"" + key + "\" : " + ((GJSON) value).encode();
			else if (value instanceof List) {
				String _result = "";
				for (Object _value : (List) value) {
					if (_value instanceof String)
						_result += ", \""
								+ _value.toString().replaceAll("\"", "\\\\\"").replaceAll("\r", "&#13;").replaceAll(
										"\n", "&#10;") + "\"";
					else if (_value instanceof Integer || _value instanceof Long || _value instanceof Float
							|| _value instanceof Double)
						_result += ", " + _value;
					else if (_value instanceof Boolean)
						_result += ", " + _value;
					else if (_value instanceof GJSON)
						_result += ", " + ((GJSON) _value).encode();
					else
						_result += ", \"\"";
				}
				if ("".equals(_result))
					_result = "[]";
				else
					_result = "[" + _result.substring(1) + "]";
				result += ", \"" + key + "\" : " + _result;
			} else
				result += ", \"" + key + "\" : \"\"";
		}
		if ("".equals(result))
			result = "{}";
		else
			result = "{" + result.substring(1) + "}";
		return result;
	}

	/**
	 * 将结果输出到页面
	 * 
	 * @param request
	 * @param response
	 */
	public void writeToPage(HttpServletRequest request, HttpServletResponse response) {
		writeToPage(request, response, encode());
	}

	/**
	 * 将传入内容输出到页面
	 * 
	 * @param request
	 * @param response
	 * @param data
	 *            字符型json数据
	 */
	public void writeToPage(HttpServletRequest request, HttpServletResponse response, String data) {
		response.setCharacterEncoding(characterEncoding);
		if (data == null || "".equals(data))
			data = "{}";
		String jsoncallback = request.getParameter(jsoncallbackMethodName);
		PrintWriter out = null;
		try {
			out = response.getWriter();
			out.write(jsoncallback == null ? data : (jsoncallback + "(" + data + ")"));
		} catch (IOException ex) {
		} finally {
			out.close();
		}
	}

	/**
	 * 获取json数据
	 * 
	 * @return 返回json数据
	 */
	public TreeMap<String, Object> getData() {
		return data;
	}

	/**
	 * 设置json数据
	 * 
	 * @param data
	 *            json数据
	 */
	public void setData(TreeMap<String, Object> data) {
		this.data = data;
	}

	/**
	 * 获取页面输出编码
	 * 
	 * @return 返回页面输出编码
	 */
	public String getCharacterEncoding() {
		return characterEncoding;
	}

	/**
	 * 设置页面输出编码
	 * 
	 * @param characterEncoding
	 *            页面输出编码
	 */
	public void setCharacterEncoding(String characterEncoding) {
		this.characterEncoding = characterEncoding;
	}

	/**
	 * 获取jQuery跨域请求回调函数名
	 * 
	 * @return 返回jQuery跨域请求回调函数名
	 */
	public String getJsoncallbackMethodName() {
		return jsoncallbackMethodName;
	}

	/**
	 * 设置jQuery跨域请求回调函数名
	 * 
	 * @param jsoncallbackMethodName
	 *            jQuery跨域请求回调函数名
	 */
	public void setJsoncallbackMethodName(String jsoncallbackMethodName) {
		this.jsoncallbackMethodName = jsoncallbackMethodName;
	}

}
